#include "SQLAggregateExpr.h"
#include "../../visitor/SQLASTVisitor.h"
#include "../SQLKeep.h"
#include "../SQLOrderBy.h"
#include "../SQLName.h"
#include "../SQLExpr.h"

SETCALSS(SQLAggregateExpr);

SQLAggregateExpr::SQLAggregateExpr(string_ptr theMethodName)
    : over(NULL),
      methodName(theMethodName)
{
  arguments = std::make_shared<std::list<SQLExpr_ptr>>();
  // methodName = theMethodName;
}

SQLAggregateExpr::~SQLAggregateExpr()
{

  // for (std::list<SQLExpr_ptr >::iterator it = arguments->begin(); it != arguments->end(); ++it)
  // {
  //   delete *it;
  // }
  // arguments->clear();

  // if (over != NULL)
  // {
  //   delete over;
  //   over = NULL;
  // }
}
SQLAggregateExpr::SQLAggregateExpr(string_ptr theMethodName, std::shared_ptr<SQLAggregateOption> theOption)
    : over(NULL),
      methodName(theMethodName),
      option(theOption)
{
  arguments = std::make_shared<std::list<SQLExpr_ptr>>();
  // methodName = theMethodName;
  // option = theOption;
}

string_ptr SQLAggregateExpr::getMethodName()
{
  return methodName;
}

void SQLAggregateExpr::setMethodName(string_ptr theMethodName)
{
  methodName = theMethodName;
}

std::shared_ptr<SQLAggregateOption> SQLAggregateExpr::getOption()
{
  return option;
}

void SQLAggregateExpr::setOption(std::shared_ptr<SQLAggregateOption> theOption)
{
  option = theOption;
}

SQLExpr_list_ptr SQLAggregateExpr::getArguments()
{
  return arguments;
}

SQLOver_ptr SQLAggregateExpr::getOver()
{
  return over;
}

void SQLAggregateExpr::setOver(SQLOver_ptr theOver)
{
  over = theOver;
}

void SQLAggregateExpr::accept0(SQLASTVisitor_ptr visitor)
{

  if (visitor->visit(SharedObject(SQLAggregateExpr)))
  {
    acceptChild(visitor, arguments);
    acceptChild(visitor, over);
  }

  visitor->endVisit(SharedObject(SQLAggregateExpr));
}

void SQLAggregateExpr::acceptChild(SQLASTVisitor_ptr visitor, SQLOver_ptr child)
{
  if (child == NULL)
  {
    return;
  }

  child->accept(visitor);
}

void SQLAggregateExpr::acceptChild(SQLASTVisitor_ptr visitor, SQLExpr_list_ptr children)
{

  if (children->empty())
  {
    return;
  }

  std::list<SQLExpr_ptr>::iterator iStart = children->begin();
  std::list<SQLExpr_ptr>::iterator iEnd = children->end();
  std::list<SQLExpr_ptr>::iterator it;
  for (it = iStart; it != iEnd; ++it)
  {
    (*it)->accept(visitor);
    // acceptChild(visitor, *it);
  }
}

void SQLAggregateExpr::setOrderBy(SQLOrderBy_ptr orderBy)
{
  if (orderBy != nullptr)
  {
    orderBy->setParent(SharedObject(SQLAggregateExpr));
  }

  this->orderBy = orderBy;
}

BOOL_ptr SQLAggregateExpr::isIgnoreNulls()
{
  if (*(this->ignoreNulls) != BOOL::NIL &&
      *(this->ignoreNulls) == BOOL::TRUE)
  {
    return BOOL::TRUE;
  }
  else
  {
    return BOOL::FALSE;
  }
}

BOOL_ptr SQLAggregateExpr::getIgnoreNulls()
{
  return this->ignoreNulls;
}

void SQLAggregateExpr::setIgnoreNulls(BOOL_ptr ignoreNulls)
{
  this->ignoreNulls = ignoreNulls;
}

BOOL_ptr SQLAggregateExpr::isWithinGroup()
{
  return withinGroup;
}

void SQLAggregateExpr::setWithinGroup(BOOL_ptr withinGroup)
{
  this->withinGroup = withinGroup;
}

SQLKeep_ptr SQLAggregateExpr::getKeep()
{
  return keep;
}

void SQLAggregateExpr::setKeep(SQLKeep_ptr keep)
{
  if (keep != nullptr)
  {
    keep->setParent(SharedObject(SQLAggregateExpr));
  }
  this->keep = keep;
}

SQLName_ptr SQLAggregateExpr::getOverRef()
{
  return overRef;
}

void SQLAggregateExpr::setOverRef(SQLName_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLAggregateExpr));
  }
  this->overRef = x;
}

SQLExpr_ptr SQLAggregateExpr::getFilter()
{
  return filter;
}

void SQLAggregateExpr::setFilter(SQLExpr_ptr x)
{
  if (x != nullptr)
  {
    x->setParent(SharedObject(SQLAggregateExpr));
  }

  this->filter = x;
}

SQLOrderBy_ptr SQLAggregateExpr::getOrderBy()
{
  return orderBy;
}

